<?php

class Unlimited
{
    
    /**
     * 有级别关系的分类（至少2级），显示在页面中看到级别的层次关系
     * 下级总是比上一级缩进一定的量，缩进的位置可以为空，也可以指定缩进符号
     * 如果某个分类有下级分类，结果数组中，上级分类后面依次是它的下级分类，然后是另一个与该上级分类同级的分类。
     *
     * 当$pid不为0，表示查找某个pid为指定值的分类的所有下级分类（结果中包含该分类）
     * 假如传参是某个分类的id，则表示查找该分类的所有下级分类（结果中不包含该分类）
     *
     * @return 一维数组。（包含有每个分类的所有信息--根据$cate）
     */
    static public function unlimitedLevel($cate, $html = '----', $pid = 0, $level = 0){
        $arr = array();
        foreach ($cate as $v) {
            if ($v['pid']  == $pid) {
                $v['level'] = $level + 1;// 最顶级的分类level级别是1。
    
                $v['html'] = str_repeat($html, $level);
                // 最顶级的分类前面没有‘----’，二级分类有一个$html，三级分类有两个$html...
    
                $arr[] = $v;
                $arr = array_merge($arr, self::unlimitedLevel($cate, $html, $v['id'], $level + 1));
            }
        }
        return $arr;
    }
    
    /**
     * @param $name 下级元素在上级元素中的key。
     * id
     * name
     * ...
     * $name =>  array(下级元素数组，每个下级元素通过递归也有可能会有自己的下级元素，同样在自己的$name键名下面列为数组)
     *
     * 当$pid不为0，表示查找某个pid为指定值的分类的所有下级分类（结果中包含该分类）
     * 假如传参是某个分类的id，则表示查找该分类的所有下级分类（结果中不包含该分类）
     *
     * @return 多维数组（包含有每个分类的所有信息--根据$cate）
     */
    static public function unlimitedMore($cate, $name = 'child', $pid = 0){
        $arr = array();
        foreach ($cate as $v) {
            if ($v['pid']  == $pid) {
                $v[$name] = self::unlimitedMore($cate, $name, $v['id']);
                $arr[] = $v;
            }
        }
        return $arr;
    }
    
    /**
     * 根据某个分类id，找到它的所有上级分类（结果中包含该分类）
     * 级别层次最高的分类位于数组最前面，其后根据层次关系排序
     *
     * 假如传参是某个分类的pid，则表示查找该分类的所有上级分类（结果中不包含该分类）
     *
     * @return 一维数组	 （包含有每个分类的所有信息--根据$cate）
     */
    static public function up($cate, $id){
        $arr = array();
        foreach ($cate as $v) {
            if ($v['id']  == $id) {
                $arr[] = $v;
                // $arr = array_merge($arr, self::upAndSelfArray($cate, $v['pid']));
                // 实际使用中，大部分用下面这种。最高级在第一个，最低级在最后一个。
                $arr = array_merge(self::up($cate, $v['pid']), $arr);
            }
        }
        return $arr;
    }
    /*
     用于路径导航：首页 >> 电子产品 >> 电脑 >> 台式机 >>&raquo; 组装机
     上面的$arr = array_merge();产生的结果是：
     id=$id的（也就是最底级的分类）位于返回数组的第一个元素，而它的最高级父元素在最后。
    
     如果想反过来，最高级分类在第一个，最底级分类在最后一个，调换array_merge()里两个数组的位置即可：
     $arr = array_merge(self::getParents($cate, $v['pid']), $arr);
     */
    
    // 向上查找，无法重组为多维数组。只有向下查找才方便操作。
    // 也可以曲线处理：先向上查找所有分类信息，然后对结果再进行向下操作，处理成多维数组。
    // 也就是把up方法的结果，作为unlimitedMore方法的参数。
    
    /**
     * 根据某个分类的id，找到它的所有上级分类id（结果中包含该指定分类的id）
     * 级别层次最高的分类的id位于数组最前面，其后根据层次关系排序
     *
     * 假如传参是某个分类的pid，则表示查找该分类的所有上级分类的id（结果中不包含该分类的id）
     *
     *@return 一维数组（元素是满足条件的分类的id）
     */
    static public function upId($cate, $id){
        //$navArray中必含id和pid。
        $arr = array();//用于存放所有满足条件的id
        foreach ($cate as $v){
            if ($v['id'] == $id){
                $arr[] = $v['id'];
                $arr = array_merge(self::upSelfId($cate, $v['pid']), $arr);
            }
        }
        return $arr;
    }
    
    /**
     * 根据某个分类的id，找到它的所有下级分类id（结果中不包含该指定分类的id）
     * 级别层次最高的分类的id位于数组最前面，其后根据层次关系排序
     *
     * 假如传参是某个分类的pid，则表示查找该分类的所有下级分类的id（结果中包含该分类）
     *
     *@return 一维数组（元素是满足条件的分类的id）
     */
    static public function downId($cate, $id){
        $arr = array();//用于存放所有满足条件的id
        foreach ($cate as $v){
            if ($v['pid'] == $id){
                $arr[] = $v['id'];
                $arr = array_merge($arr, self::downAllId($cate, $v['id']));
            }
        }
        return $arr;
    }
    
    
    /**
     * 根据某个分类的id，找到它的直接下级分类id（只找pid == 该分类id的分类的id）
     *
     *@return 一维数组（元素是满足条件的分类的id）
     */
    static public function downChildId($cate,$id){
        $arr = array();//用于存放所有满足条件的id
        foreach ($cate as $v){
            if ($v['pid'] == $id){
                $arr[] = $v['id'];
            }
        }
        return $arr;
    }
    
    
    //考虑一个需求
    // 对于已经重组后的具有child元素的多维数组，结合extjs的tree，child元素不为空的展开，为空的则leaf:true
    static public function leaf($arrMore, $child = 'child'){
        foreach ($arrMore as $k => $v) {
            if (empty($v[$child])) {
                $arrMore[$k]['leaf'] = true;
                $arrMore[$k][$child] = self::leaf($v[$child], $child);
            }else{
                $arrMore[$k]['expanded'] = true;
                $arrMore[$k][$child] = self::leaf($v[$child], $child);
            }
        }
        return $arrMore;
    }
    
}

?>